////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//         This file is distributed under the BSD 2-Clause open source license. See Licenses/License.txt for details.         //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "WNScripting/inc/WNStructAllocation.h"
#include "WNScripting/inc/WNCodeModule.h"
#include "WNScripting/inc/WNTypeNode.h"
#include "WNScripting/inc/WNNodeHelpers.h"

#ifdef _WN_MSVC
    #pragma warning(push)
    #pragma warning(disable: 4100)
    #pragma warning(disable: 4127)
    #pragma warning(disable: 4152)
    #pragma warning(disable: 4244)
    #pragma warning(disable: 4245)
    #pragma warning(disable: 4267)
    #pragma warning(disable: 4355)
    #pragma warning(disable: 4512)
#endif

#include "llvm/IR/IRBuilder.h"

#ifdef _WN_MSVC
    #pragma warning(pop)
#endif


using namespace WNScripting;

WNStructAllocation::WNStructAllocation() :
    mType(WN_NULL) {
}

WNStructAllocation::~WNStructAllocation() {
    if(mType) {
        WN_DELETE(mType);
    }
}

WN_VOID WNStructAllocation::SetType(WNTypeNode* _type) {
    mType = _type;
}

eWNTypeError WNStructAllocation::GenerateCode(WNCodeModule& _module, const WNFunctionDefinition* _def, WNLogging::WNLog& _compilationLog) {
    WNScriptType structType = WN_NULL;
    eWNTypeError err = eWNOK;
    if(eWNOK != (err = mType->GetType(_module, structType))) {
        return(err);
    }
    if(!structType->mLLVMStructType) {
        _compilationLog.Log(WNLogging::eError, 0, structType->mName, " is not a valid Struct Type");
        LogLine(_compilationLog, WNLogging::eError);
        return(eWNBadType);
    }
    llvm::Value* outValue = NULL;
    if(eWNOK != (err = AllocateStruct(_module, outValue, structType, _def, _compilationLog))){
        _compilationLog.Log(WNLogging::eError, 0, "Cannot allocate Struct: ", structType->mName);
        LogLine(_compilationLog, WNLogging::eError);
        return(err);
    }

    mValue = outValue;
    mScriptType = structType;
    return(eWNOK);
}

